package io.sundial.repository;

import io.sundial.core.lifecycle.Lifecycle;
import io.sundial.repository.exception.KeyConflictedException;
import io.sundial.repository.exception.KeyNotFoundException;

import java.util.Enumeration;

/**
 * 数据仓储接口
 *
 * @author Payne 646742615@qq.com
 * 2018/12/18 9:51
 */
public interface Repository<K, V> extends Lifecycle {

    /**
     * 根据数据索引查找数据单元，如果不存在将返回{@code null}
     *
     * @param key 数据索引
     * @return 数据单元
     */
    V find(K key);

    /**
     * 保存一个数据单元，其中key为数据的索引，value为数据的内容，当索引已存在时将抛出{@link KeyConflictedException}异常，
     * 如果发生内部异常将抛出{@link RepositoryException}异常
     *
     * @param key   数据索引
     * @param value 数据内容
     * @throws RepositoryException 仓储异常
     * @see KeyConflictedException
     */
    void save(K key, V value) throws RepositoryException;

    /**
     * 替换指定数据索引的数据内容，如果指定的数据索引不存在时将抛出{@link KeyNotFoundException}异常，
     * 如果发生内部异常将抛出{@link RepositoryException}异常
     *
     * @param key   数据索引
     * @param value 数据内容
     * @throws RepositoryException 仓储异常
     * @see KeyNotFoundException
     */
    void replace(K key, V value) throws RepositoryException;

    /**
     * 删除指定数据索引的数据单元，如果删除成功则返回{@code true}，否则返回{@code false}即数据单元不存在
     *
     * @param key 数据索引
     * @return 如果删除成功则返回{@code true}，否则返回{@code false}
     */
    V remove(K key);

    /**
     * 判断指定数据索引的数据单元是否存在，如果存在则返回{@code true}，不存在则返回{@code false}
     *
     * @param key 数据索引
     * @return 如果存在则返回{@code true}，不存在则返回{@code false}
     */
    boolean contains(K key);

    /**
     * 获取数据索引迭代器
     *
     * @return 数据索引迭代器
     */
    Enumeration<K> keys();

    /**
     * 获取数据单元迭代器
     *
     * @return 数据单元迭代器
     */
    Enumeration<V> values();

}
